var Rx = require("rxjs");
var chatModel = require("../model/chatModel");
var accountModel = require("../model/accountModel");

var operators = require("rxjs/operators");
var SERVER_CONST = require("../server-const");
var express = require("express");
var router = express.Router();

var modalCollection = require("../model/collectionModel");

var files = chatModel.files;
var user = chatModel.user;
var channels = chatModel.channels;
var teams = chatModel.teams;
var channelMembers = chatModel.channelMembers;
var teamMembers = chatModel.teamMembers;
var collectionItem = modalCollection.collectionItem;
var mongoose = require("mongoose");
var path = require("path");
const SUCCESS_CODE = 0;
const ERROR_CODE = 1;
const NOT_CORRECT_CODE = 2;
var fs = require("fs");
var moment = require("moment");
const { dirname } = require("path");
let appRootPath = path.resolve("./");

let envConfig = require("../config." + process.env.NODE_ENV + ".js");
const utils = {
	//获取环境
	getEnv() {
		return envConfig;
	},
	//上传文件，生成文件
	createFile(file, PostFileType, UserId, ChannelId, PostId, MimeType) {
		return new Promise((resolve, reject) => {
			//上传时间 用来生成文件名字
			let time = new Date().getTime();
			//上传日期 用作生成文件夹目录
			let fileDate = moment().format("YYYY-MM-DD");
			//文件名
			let name = `${new Date().getTime().toString()}_${file.name}`;
			//文件名
			let DisplayName = `${file.name}`;
			//物理地址,这个地址会用在新建文件夹上,也就是建目录的时候用,不可以写成相对路径,否则linux环境生成不了目录
			//let dir = "./routes/temp/" + fileDate;
			let dir = appRootPath + "/temp/" + fileDate;
			//判断文件是否存在,如果不存在,则递归生成文件夹
			if (!fs.existsSync(dir)) {
				fs.mkdirSync(dir, {
					recursive: true,
				});
			}
			//savePath 是生成文件时,该文件存在什么地方
			let savePath = `${dir}/${name}`;
			//预览时,访问接口的地址.这个地址是调用接口时用的.注意不带日期的目录
			//let PreviewPath = "http://www.37talk.com" + "/api/file/temp/" + name;
			let PreviewPath =
				"http://" + envConfig.host + ":" + envConfig.port + "/file/temp/" + name;
			//这个地址是实际存储的物理地址.调用接口后,express会往这个地址找文件,然后返回给前台预览.
			//let path = __dirname + "/temp/" + fileDate + "/" + name;
			let path = appRootPath + "/temp/" + fileDate + "/" + name;
			//文件后缀
			let Extension = file.name.split(".")[1];
			//文件大小
			let Size = file.size;

			file.mv(savePath, function (err) {
				if (err) {
					//return res.status(500).send(err);
					reject(err);
				} else {
					let obj = {
						PostFileType: PostFileType,
						FileType: Extension,
						CreateAt: time,
						UpdateAt: time,
						EditAt: time,
						DeleteAt: time,
						UserId: UserId,
						ChannelId: ChannelId,
						PostId: PostId,
						Path: path,
						ThumbnailPath: PreviewPath,
						PreviewPath: PreviewPath,
						Name: name,
						DisplayName: DisplayName,
						Extension: Extension,
						Size: Size,
						MimeType: MimeType,
						Width: null,
						Height: null,
						HasPreviewImage: null,
						Props: null,
						Hashtags: null,
					};
					if (!err) {
						switch (PostFileType) {
							case "CustomEmoji":
								new files(obj).save(function (err, result) {
									util.getUserInfo(UserId).exec(function (err, result) {
										if (err) {
											reject(err);
										} else {
											resolve({
												...result[0],
											});
										}
									});
								});
								break;
							case "img":
								new files(obj).save(function (err, result) {
									if (err) {
										reject(err);
									} else {
										resolve({
											CreatorId: result._doc.UserId,
											_id: result._doc._id,
											CreateAt: result._doc.CreateAt,
											PreviewPath: result._doc.PreviewPath,
											FileType: result._doc.FileType,
											Extension: result._doc.Extension,
											Size: result._doc.Size,
											DisplayName: result._doc.DisplayName,
											Name: result._doc.Name,
										});
									}
								});
								break;
							case "file":
								new files(obj).save(function (err, result) {
									if (err) {
										reject(err);
									} else {
										resolve({
											...Object.assign(obj, {
												CreatorId: result._doc.UserId,
												_id: result._doc._id,
												CreateAt: result._doc.CreateAt,
												PreviewPath: result._doc.PreviewPath,
												FileType: result._doc.FileType,
												Extension: result._doc.Extension,
												Size: result._doc.Size,
												DisplayName: result._doc.DisplayName,
												Name: result._doc.Name,
											}),
										});
									}
								});
								break;
							case "avatar":
								files
									.update(
										{
											UserId: UserId,
											PostFileType: "avatar",
										},
										{
											$set: obj,
										},
										{
											upsert: true,
										}
									)
									.exec(function (err, result) {
										if (err) {
											reject(err);
										} else {
											files
												.aggregate([
													{
														$match: {
															UserId,
															PostFileType: "avatar",
														},
													},
												])
												.exec((err, results) => {
													if (err) {
														reject(err);
													} else {
														let result = results[0];
														resolve({
															...Object.assign(obj, {
																CreatorId: result.UserId,
																_id: result._id,
																CreateAt: result.CreateAt,
																PreviewPath: result.PreviewPath,
																FileType: result.FileType,
																Extension: result.Extension,
																Size: result.Size,
																DisplayName: result.DisplayName,
																Name: result.Name,
															}),
														});
													}
												});
										}
									});
								break;
						}
					}
				}
			});
		});
	},

	//将消息处理成前台能解析的字段格式
	formatMsgContent() {
		return [
			{
				$lookup: {
					from: "users",
					as: "users",
					let: {
						userId: "$UserId",
					},
					pipeline: [
						{
							$match: {
								$expr: {
									$eq: ["$$userId", "$_id"],
								},
							},
						},
					],
				},
			},
			{
				$lookup: {
					from: "files",
					localField: "users._id",
					foreignField: "UserId",
					as: "files",
				},
			},
			{
				$unwind: {
					path: "$users",
				},
			},
			{
				$project: {
					Additional: "$Additional",
					AtWhoList: "$AtWhoList",
					ChannelId: "$ChannelId",
					CreateAt: "$CreateAt",
					Email: "$users.Email",
					Message: "$Message",
					PostId: "$_id",
					Prefix: "$users.Prefix",
					UpdateAt: "$UpdateAt",
					Type: "$Type",
					UserId: "$users._id",
					Username: "$users.Username",
					PostFileType: "$FileType",
					FileDisplayName: "$FileDisplayName",
					PreviewPath: "$PreviewPath",
					FileSize: "$FileSize",
					FileType: "$FileType",
					avatar: {
						$filter: {
							input: "$files",
							as: "files",
							cond: {
								$and: [
									{
										$eq: ["$$files.UserId", "$users._id"],
									},
									{
										$eq: ["$$files.PostFileType", "avatar"],
									},
								],
							},
						},
					},
				},
			},
		];
	},

	//如果含有相同的PostId和CreatorId，则先清掉，再插入
	deleteCollectionItems({ PostId, CreatorId }) {
		return new Promise((resolve, reject) => {
			collectionItem
				.deleteMany({
					PostId,
					CreatorId,
				})
				.exec((err, result) => {
					if (err) {
						reject(err);
					} else {
						resolve(result);
					}
				});
		});
	},

	//生成当前时间字符串
	generateNow() {
		return new Date().getTime().toString();
	},

	//检查是否登录
	checkAuth: (req, res, next) => {
		if (!req.headers.token || req.headers.token == "null") {
			res.status(401).json({
				code: ERROR_CODE,
			});
		} else {
			//校验token
			// if (req.headers.token != "token12345678") {
			// 	res.status(401).json({
			// 		code: ERROR_CODE,
			// 	});
			// }
			// else {
			// 	next();
			// }

			//暂不处理 , 只要token 不为空 , 就让过
			next()

		}
	},

	res: {
		//返回正确的响应，但查询有误，例如 ：标签名重复等
		notCorrect: ({ res, data, msg }) => {
			res.json({
				code: NOT_CORRECT_CODE,
				data,
				msg,
			});
		},
		//返回正确的响应
		success: ({ res, data, msg }) => {
			res.json({
				code: SUCCESS_CODE,
				data,
				msg: "success",
			});
		},
		//服务器错误
		error: ({ res, data, msg }) => {
			res.status(503).json({
				code: ERROR_CODE,
				data,
				msg,
			});
		},
	},
	//生成channelRoom
	//channel,是对象,channelInfo
	generateChannelRoom(ChannelId) {
		return `channel:${ChannelId}`;
	},
	//检查两个userid是否有私聊channel
	findPrivateChatIsExist: (fromId, toId, handler) => {
		channelMembers
			.aggregate([
				{
					$group: {
						_id: "$ChannelId",
						UserId: {
							$push: "$UserId",
						},
						count: {
							$sum: 1,
						},
					},
				},
				{
					$match: {
						$and: [
							{
								UserId: {
									$eq: fromId,
								},
							},
							{
								UserId: {
									$eq: toId,
								},
							},
							{
								count: 2,
							},
						],
					},
				},
				{
					$lookup: {
						from: "channels",
						localField: "_id",
						foreignField: "_id",
						as: "channels",
					},
				},
				{
					$unwind: {
						path: "$channels",
					},
				},
				{
					$match: {
						"channels.Type": {
							$eq: "private",
						},
					},
				},
				{
					$replaceRoot: {
						newRoot: "$channels",
					},
				},
			])
			.exec(function (err, fresult) {
				//要过滤掉默认所有人群组
				handler(fresult[0]);
			});
	},
	getUserInfo: (UserId) => {
		return user.aggregate([
			{
				$match: {
					_id: {
						$eq: UserId,
					},
				},
			},
			{
				$lookup: {
					from: "files",
					let: {
						userId: "$_id",
					},
					as: "customEmoji",
					pipeline: [
						{
							$match: {
								$expr: {
									$and: [
										{
											$eq: ["$$userId", "$UserId"],
										},
										{
											$eq: ["$PostFileType", "CustomEmoji"],
										},
									],
								},
							},
						},
						{
							$sort: {
								CreateAt: -1,
							},
						},
					],
				},
			},
			{
				$lookup: {
					from: "files",
					let: {
						userId: "$_id",
					},
					as: "avatar",
					pipeline: [
						{
							$match: {
								$expr: {
									$and: [
										{
											$eq: ["$$userId", "$UserId"],
										},
										{
											$eq: ["$PostFileType", "avatar"],
										},
									],
								},
							},
						},
					],
				},
			},
		]);
	},
};

module.exports = utils;
